(function($){
    $.extend({pushlet: {}});

    var COOKIE_NAME = 'pl_s_l';
    var _CONTEXTPATH = getContextPath();
    var SUBJECTS_GAP = "/";
    var SUBJECT_LABEL_GAP = "@";
    
    function getContextPath() {
        var pathName = document.location.pathname;
        var index = pathName.substr(1).indexOf("/");
        var result = pathName.substr(0,index+1);
        return result;
    }

    function _setCookie(cv) {
        var date = new Date();
        date.setTime(date.getTime() + 43200000); // 12小时;
        $.cookie(COOKIE_NAME, cv, {path: '/', expires: date});
    }

    function setCookie(aSubject, aLabel) {
        var ss = $.cookie(COOKIE_NAME);
        var cv = aSubject;
        aLabel && (cv += SUBJECT_LABEL_GAP + aLabel);
        cv += SUBJECTS_GAP;
        if (ss && ss.indexOf(cv) != -1)
            return;
        ss && (ss != null) && (cv += ss);
        _setCookie(cv);
    }

    function rmCookie(aSubject, aLabel) {
        if (aSubject == undefined) {
            $.cookie(COOKIE_NAME, null, {path: '/'});
            return;
        }
        var cv = aSubject;
        aLabel && (cv += SUBJECT_LABEL_GAP + aLabel);
        cv += SUBJECTS_GAP;
        var ss = $.cookie(COOKIE_NAME);
        ss && (ss = ss.replace(new RegExp(cv, "gm"), ""))
        _setCookie(ss);
    }

    $.pushlet.resubscribe = function() {
        var ss = $.cookie(COOKIE_NAME);
        if (ss) {
            var sss = ss.split(SUBJECTS_GAP);
            for (var i = 0, size = sss.length; i < size; i++) {
                var s = sss[i].split(SUBJECT_LABEL_GAP);
                (s.length == 2) ? $.pushlet.subscribe(s[0], s[1]) : $.pushlet.subscribe(s[0]);
            }
        }
    }

    $.pushlet.join = function(aId) {
    	var query = PL.NV_P_FORMAT + '&' + PL.NV_P_MODE;
    	aId && (query += "&p_id=" + aId) && (PL.sessionId = aId);
        PL._doRequest('join', query);
    }

    $.pushlet.listen = function(aSubject, aLabel) {
        var query = PL.NV_P_MODE;
        aSubject && (query += '&p_subject=' + aSubject);
        aLabel && (query += '&p_label=' + aLabel);
        aSubject && setCookie(aSubject, aLabel);
        PL._doRequest('listen', query);
    }

    $.pushlet.joinListen = function(aId, aSubject, aLabel) {
    	PL._setStatus('join-listen ' + aSubject);
        PL.sessionId = aId;
        var query = PL.NV_P_FORMAT + '&' + PL.NV_P_MODE;
        query += "&p_id=" + aId;
        aSubject && (query += '&p_subject=' + aSubject);
        aLabel && (query += '&p_label=' + aLabel);
        aSubject && setCookie(aSubject, aLabel);
        PL._doRequest('join-listen', query);
    }

    $.pushlet.leave = function() {
        rmCookie();
    	PL._doRequest('leave');
    }

    $.pushlet.heartbeat = function() {
    	PL._doRequest('hb');
    }

    $.pushlet.publish = function(aSubject, aLabel_data) {
    	var query = 'p_subject=' + aSubject;
    	var data, aLabel;
    	var args = $.pushlet.publish.arguments;
    	(args.length == 3) ? (aLabel = args[1], data = args[2]) : (data = args[1]); 
    	aLabel && (query += '&p_label=' + aLabel);
        for (var arg in data) {
        	query += "&" + arg + "=" + data[arg];
        }
        PL._doRequest('publish', query);
    }
    
    $.pushlet.ajax = function(params) {
    	var subject = params.subject;
    	var label = params.label;
    	var pid = params.pid;
    	
    	var type = params.type || "GET";
        var dataType = params.dataType || "JSON";
        var url = params.url;
        var success = params.success;
        var error = params.error;
        var data = params.data;
        var async = params.async;
        
        if (data) {
        	subject && (data.subject = subject);
        	label && (data.label = label);
        	pid && (data.pid = pid);
        } else {
        	if (url.indexOf("?") > -1) {
        		subject && (url += "&subject=" + subject);
            	label && (url += "&label=" + label);
            	pid && (url += "&pid=" + pid);
        	} else {
        		url += "?r=";
        		subject && (url += "&subject=" + subject);
            	label && (url += "&label=" + label);
            	pid && (url += "&pid=" + pid);
        	}
        }
        
        $.ajax({
            "type": type,
            "async": async,
            "dataType": dataType,
            "url": _CONTEXTPATH+url,
            "data": data,
            "success": success,
            "error": error
        });
    }

    $.pushlet.unicast = function(pid, aSubject, aLabel_data) {
    	var query = 'p_subject=' + aSubject + "&p_to=" + pid;
    	var data, aLabel;
    	var args = $.pushlet.publish.arguments;
    	(args.length == 4) ? (aLabel = args[2], data = args[3]) : (data = args[2]); 
    	aLabel && (query += '&p_label=' + aLabel);
        for (var arg in data) {
        	query += "&" + arg + "=" + data[arg];
        }
        PL._doRequest('publish', query);
    }
    
    $.pushlet.subscribe = function(aSubject, aLabel) {
    	var query = 'p_subject=' + aSubject;
        aLabel && (query += '&p_label=' + aLabel);
        aSubject && setCookie(aSubject, aLabel);
        PL._doRequest('subscribe', query);
    }

    $.pushlet.unsubscribe = function(aSubject, aLabel) {
    	var query;
        // If no aSubject we unsubscribe from all subscriptions
        aSubject && (query = 'p_subject=' + aSubject);
        aLabel && (query += '&p_label=' + aLabel);
        rmCookie(aSubject, aLabel);
        PL._doRequest('unsubscribe', query);
    }
    
    $.pushlet.setDebug = function(bool) {
    	PL.debugOn = bool;
    }

})(jQuery);
